home *** CD-ROM | disk | FTP | other *** search
-
- {
- This is a very simple editor for ascii text files. It uses an array of
- pointers and dynamic memory allocation for every line, so that lines can
- easily be inserted or deleted without moving huge amounts of data.
- There is no saving available, but this should be easy to include.
-
- I recommend compiling this as a protected mode application (far more
- memory available), but you can also use it in real mode, if you want.
- You can edit texts of every size (no 64K limit), they just have to fit
- into your memory.
-
- This is Public Domain, feel free to use it for whatever you like, but at
- your own risk !
-
- Any questions, comments, etc. : heiner@rummelplatz.uni-mannheim.de
- Alexander Heiner
- }
-
- uses crt,dos;
- {$F+}
-
- type
- D_LStr = record
- StrLen: word;
- Str: array[0..16383] of byte;
- end;
- P_LStr = ^D_Lstr;
-
- D_TmpStr=array[0..16383] of char;
-
- var
- LStr: array[0..16000] of P_LStr;
- TmpStr: ^D_TmpStr;
- YscrlPos,XscrlPos:longint;
- CrX,CrY:word;
- MaxLines:longint;
- ch:char;
- FName:string;
-
- procedure OutString(x,y:word;s:string;tcol,bcol:byte);
- var p:pointer;
- begin
- p:=@s;
- asm
- push ds
- mov ax,SegB800
- lds si,p
- mov es,ax
- imul di,y,160
- mov ax,x
- shr ax,1
- add di,ax
- mov ah,bcol
- shl ah,4
- add ah,tcol
- mov cl,ds:[si]
- inc si
- @l1:
- lodsb
- stosw
- dec cl
- jnz @l1
-
- pop ds
- end;
- end;
-
- procedure LoadText(Fname:string);
- var f:text;a,b:word;s:string;gmem:longint;
- begin
- getmem(tmpStr,16384);
- assign(f,Fname);
- reset(f);
- a:=0;gmem:=0;
- while not eof(f) do begin
- readln(f,TmpStr^);
- b:=0;while TmpStr^[b]<>#0 do inc(b);
-
- if memavail>=2+b then begin
- getmem(LStr[a],2+b);
- move(TmpStr^,LStr[a]^.Str,b);
- Lstr[a]^.StrLen:=b;
- inc(gmem,b+2);
- end else begin outstring(0,3,'Not enough memory.',7,0);halt(1);end;
-
- inc(a);if a>16000 then begin
- outstring(0,3,'Line overflow (max.16000)',7,0);halt(1);end;
-
- str(a,s);outstring(0,0,'lines loaded: '+s,7,0);
- str(gmem,s);outstring(0,1,'memory allocated: '+s+ ' bytes',7,0);
- end;
- MaxLines:=a-1;
- freemem(tmpStr,16384);
- end;
-
- procedure ShowAllText;
- var x,y,len:word;s:string;
- begin
- for y:=0 to 23 do begin
- s:='';
- if LStr[y+Yscrlpos]<>NIL then begin
- len:=LStr[y+Yscrlpos]^.StrLen;
- if len>XscrlPos then begin
- dec(len,XScrlPos);
- if len>80 then len:=80;
- move(LStr[y+Yscrlpos]^.Str[XScrlPos],s[1],len);
- s[0]:=chr(len);
- end;
- end;
- while s[0]<#80 do s:=s+' ';
- OutString(0,y,s,11,0);
- end;
- end;
-
- procedure ScrollDown;
- begin
- if YScrlPos>=(MAxLines-23) then exit;
- inc(YScrlPos);
- ShowAllText;
- end;
-
- procedure ScrollUp;
- begin
- if YScrlPos<1 then exit;
- dec(YScrlPos);
- ShowAllText;
- end;
-
- procedure ScrollRight;
- begin
- inc(XScrlPos);
- ShowAllText;
- end;
-
- procedure ScrollLeft;
- begin
- if XScrlPos<1 then exit;
- dec(XScrlPos);
- ShowAllText;
- end;
-
- procedure InsertChar(ch:char);
- var l1,add:word;
- begin
- inc(CrX,XScrlPos);
- l1:=LStr[CrY+YscrlPos]^.StrLen;
- if (CrX+1)<=l1 then add:=1 else add:=(crx+1)-l1;
-
- getmem(TmpStr,l1+add);
- move(LStr[CrY+YscrlPos]^.Str,TmpStr^,l1);
- if (CrX+1)<=l1 then move(TmpStr^[CrX],TmpStr^[CrX+1],l1-crx) else
- fillchar(TmpStr^[l1],crx-l1,32);
- TmpStr^[Crx]:=ch;
-
- freemem(LStr[CrY+YscrlPos],2+l1);
- getmem(LStr[CrY+YscrlPos],2+l1+add);
-
- move(TmpStr^,LStr[CrY+YscrlPos]^.Str,l1+add);
- LStr[CrY+YscrlPos]^.StrLen:=l1+add;
-
- freemem(TmpStr,l1+add);
- dec(CrX,XScrlPos);
-
- if CrX=79 then ScrollRight else inc(CrX);
- ShowAllText;
- gotoxy(CrX+1,CrY+1);
- end;
-
- procedure DeleteLine(Lpos:byte);
- var y,l1,l2:word;
- begin
- l1:=LStr[Lpos-1]^.StrLen;
- l2:=LStr[Lpos]^.StrLen+l1;
- getmem(TmpStr,l2);
-
- move(LStr[Lpos-1]^.Str,TmpStr^,l1);
- move(LStr[Lpos]^.Str,TmpStr^[l1],Lstr[Lpos]^.StrLen);
- freemem(LStr[Lpos-1],l1+2);
- getmem(LStr[Lpos-1],l2+2);
- move(TmpStr^,LStr[Lpos-1]^.Str,l2);
- LStr[Lpos-1]^.StrLen:=l2;
-
- dec(MaxLines);
- freemem(Lstr[Lpos],LStr[Lpos]^.StrLen+2);
- for y:=Lpos to MaxLines do LStr[y]:=Lstr[y+1];
- LStr[MaxLines+1]:=NIL;
- freemem(TmpStr,l2);
-
- if CrY=0 then ScrollUp else begin dec(CrY);ShowAllText;end;
- Crx:=l1;
- gotoxy(CrX+1,CrY+1);
- end;
-
- procedure DeleteChar;
- var l1:word;
- begin
- inc(CrX,XScrlPos);
- if Crx=0 then begin
- DeleteLine(Cry+YscrlPos);
- exit;
- end;
- l1:=LStr[CrY+YscrlPos]^.StrLen;
-
- getmem(TmpStr,l1);
- move(LStr[CrY+YscrlPos]^.Str,TmpStr^,l1);
- move(TmpStr^[CrX],TmpStr^[CrX-1],l1-crx);
-
- freemem(LStr[CrY+YscrlPos],2+l1);
- getmem(LStr[CrY+YscrlPos],2+l1-1);
-
- move(TmpStr^,LStr[CrY+YscrlPos]^.Str,l1-1);
- LStr[CrY+YscrlPos]^.StrLen:=l1-1;
-
- freemem(TmpStr,l1);
- dec(CrX,XScrlPos);
-
- if CrX=0 then ScrollLeft else dec(CrX);
- ShowAllText;
- gotoxy(CrX+1,CrY+1);
- end;
-
- procedure InsertLine;
- var y,l1:word;
- begin
- inc(CrX,XScrlPos);
- inc(MaxLines);
- l1:=LStr[YscrlPos+CrY]^.StrLen;
- for y:=MaxLines-1 downto Yscrlpos+CrY+1 do LStr[y+1]:=Lstr[y];
-
- if (CrX>=l1)or(l1=0) then begin
- getmem(LStr[YscrlPos+CrY+1],2+1);
- LStr[YscrlPos+CrY+1]^.StrLen:=0;
- end else begin
- getmem(LStr[YscrlPos+CrY+1],2+(l1-crx));
- move(LStr[YscrlPos+CrY]^.Str[CrX],LStr[YscrlPos+CrY+1]^.Str,l1-crx);
- LStr[YscrlPos+CrY+1]^.StrLen:=l1-crx;
-
- getmem(TmpStr,crx+1);
- move(LStr[YscrlPos+CrY]^.Str,TmpStr^,crx);
- freemem(LStr[YscrlPos+CrY],2+l1);
- getmem(LStr[YscrlPos+CrY],2+crx);
- move(TmpStr^,LStr[YscrlPos+CrY]^.Str,crx);
- LStr[YscrlPos+CrY]^.StrLen:=crx;
- freemem(TmpStr,crx+1);
- end;
- dec(CrX,XScrlPos);
-
- XScrlPos:=0;
- ShowAllText;
- CrX:=0;
- if CrY=23 then ScrollDown else inc(CrY);
- gotoxy(CrX+1,CrY+1);
- end;
-
-
- {----- cursor control ------------------------------------------------------}
-
- procedure CursorDown;
- begin
- if Cry+YscrlPos>=MAxLines then exit;
- if CrY=23 then ScrollDown else inc(CrY);
- gotoxy(CrX+1,CrY+1);
- end;
-
- procedure CursorUp;
- begin
- if CrY=0 then ScrollUp else dec(CrY);
- gotoxy(CrX+1,CrY+1);
- end;
-
- procedure CursorRight;
- begin
- if CrX=79 then ScrollRight else inc(CrX);
- gotoxy(CrX+1,CrY+1);
- end;
-
- procedure CursorLeft;
- begin
- if CrX=0 then ScrollLeft else dec(CrX);
- gotoxy(CrX+1,CrY+1);
- end;
-
- procedure CursorAtLineEnd;
- begin
- CrX:=LStr[YscrlPos+CrY]^.StrLen;
- if CrX>79 then begin XScrlPos:=CrX-79;CrX:=79; end else begin
- if CrX>XScrlPos then dec(CrX,XScrlPos) else XScrlPos:=0;
- end;
- gotoxy(CrX+1,CrY+1);
- ShowAllText;
- end;
-
- procedure CursorAtLineStart;
- begin
- XScrlPos:=0;
- CrX:=0;
- gotoxy(1,CrY+1);
- ShowAllText;
- end;
-
- procedure PageDown;
- begin
- inc(YscrlPos,22);if yscrlpos>MaxLines-23 then Yscrlpos:=Maxlines-23;
- ShowAllText;
- end;
-
- procedure PageUp;
- begin
- dec(YscrlPos,22);if yscrlpos<0 then Yscrlpos:=0;
- ShowAllText;
- end;
-
-
- {----- status line ---------------------------------------------------------}
-
- procedure ShowStats;
- var s,s2,s3:string;
- begin
- str(CrY+YScrlPos+1,s);
- str(MaxLines+1,s2);
- s3:=' '+FName;
- if s3[0]>#40 then s3[0]:=#40;
- while s3[0]<#40 do s3:=s3+' ';
-
- s3:=s3+'Line: '+s+' / '+s2+' Row: ';
- str(CrX+XScrlPos+1,s);
- str(LStr[YscrlPos+CrY]^.StrLen,s2);
- s3:=s3+s+' / '+s2;
- while s3[0]<#80 do s3:=s3+' ';
-
- OutString(0,24,s3,0,7);
- end;
-
-
- {----- main ----------------------------------------------------------------}
-
- begin
-
- FName:='test.doc';
-
- clrscr;
- XscrlPos:=0;YscrlPos:=0;CrX:=0;CrY:=0;
-
- LoadText(FName);
- ShowAllText;
- ShowStats;
- gotoxy(1,1);
-
- repeat
- repeat until keypressed;
- ch:=readkey;
- if ch=#0 then begin
- ch:=readkey;
- if ch=#80 then CursorDown;
- if ch=#72 then CursorUp;
- if ch=#77 then CursorRight;
- if ch=#75 then CursorLeft;
- if ch=#71 then CursorAtLineStart;
- if ch=#79 then CursorAtLineEnd;
- if ch=#81 then PageDown;
- if ch=#73 then PageUp;
- ShowStats;
- end else begin
- if ch<>#27 then
- if ch=#8 then DeleteChar else
- if ch=#13 then InsertLine else
- InsertChar(ch);
- ShowStats;
- end;
- until ch=#27;
- end.
-
-